home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / New System Software Extensions / OpenDoc A6 / OpenDoc Parts Framework / Documentation / Utilities Component / Utilities Component
Encoding:
Text File  |  1994-04-21  |  43.8 KB  |  288 lines  |  [ONLN/HLX2]

  1. Utilities Component
  2.  
  3. Introduction
  4. The Utilities component is a collection of miscellaneous utilities which don’t logically belong in the other OPF components. Currently, there is only one utility in the Utilities component: the reference counting utility.
  5. Utilities Component Overview
  6. The Utilities component contains 1 class and 11 methods. You will likely need to know about, and use, the majority of the Utilities component methods.
  7. Directory
  8. FWFoundU
  9. Heritage
  10. FW_TCountedPtr    3
  11. Utilities component classes
  12. There is only one class in the Utilities component, FW_TCountedPtr, which is at the root level of the Utilities component.
  13. Utilities component concepts
  14. The Utilities component provides the reference-counted pointer template class, FW_TCountedPtr, to make it easier to use reference counting. The goal of reference counting is to keep track of how many times an object is referenced so an unreferenced object can be automatically deleted. For more information on reference counting, see “Using FW_TCountedPtr” on page 3.
  15. Additional Utilities component interfaces
  16. There are no additional interfaces.
  17. Component dependencies
  18. Reference-counted pointers are particularly useful when the pointers are value-based, automatic (stack-based) variables. This is true because OPF takes advantage of C++ exception handling. If a reference-counted pointer is a stack-based variable in a given scope, and an exception is thrown out of the scope, then it is important that the destructor of the reference-counted pointer is executed. When OPF is built with compilers that do not yet provide exception handling, OPF uses the OPF Exception Library to provide exception handling emulation. FW_TCountedPtr depends upon exception handling, so if the compiler does not support exception handling, FW_TCountedPtr depends upon the BEL component, FWExcLib. When OPF is built with compilers that support exception handling, FW_TCountedPtr is entirely self-contained and is not dependent on any other OPF components.
  19. Using the Utilities Component
  20. Use the Utilities component to keep track of how many times an object is referenced so an unreferenced object can be automatically deleted.
  21. Subclassing within the Utilities component
  22. Although you can subclass FW_TCountedPtr, that is generally not good C++ style. Instead, you will typically be instantiating FW_TCountedPtr.
  23. Instantiating within the Utilities component
  24. You instantiate the class FW_TCountedPtr.
  25. Extending the Utilities component
  26. It is generally not necessary to extend the Utilities component.
  27. Catching Utilities component exceptions
  28. Methods in the Utilities component do not throw exceptions.
  29. Platform dependencies in the Utilities component
  30. There are no platform-dependent methods in this component.
  31. FW_TCountedPtr Class
  32. Introduction
  33. FW_TCountedPtr provides a mechanism for reference-counted pointers. A reference-counted pointer points to an object of a specific type (tRepresentation) that must contain an internal reference count.
  34. Use FW_TCountedPtr to adjust the reference count inside the representation object. When a reference-counted pointer is:
  35. •    copied, the reference count in the representation object is incremented.
  36. •    deleted, the reference count in the representation object is decremented.
  37. Disposing of a single reference-counted pointer does not delete the representation object, if it is still being accessed by other reference-counted pointers. When the reference count goes to zero, the representation object is deleted.
  38. Header file
  39. FWCouPtr.h
  40. Heritage
  41. FW_TCountedPtr
  42. Using FW_TCountedPtr
  43. Use FW_TCountedPtr for classes whose instances are often copied through assignment or parameter passing, particularly if the objects are so large or complex that copying is expensive. In addition, use reference-counted pointers when multiple logical copies of an object might exist, though the data itself cannot be copied.
  44. Overview of reference counting
  45. Suppose you are developing a part where you will have many string objects which might contain a small set of string values. Assume you want to create a string class, CString, that can minimize storage requirements by sharing the representation for the string data when two CString objects contain the same string data. The representation is itself an object, managing the shared data and an associated reference count. You will need to design two classes: CString and CStringRep.
  46. In the class CString, implement the assignment operator (among others) such that assigning one string to another string causes sharing of the representation.
  47.  
  48. class CString
  49. {
  50. public:
  51. operator=(const CString& other);
  52. private:
  53. CStringRep *fRep;                                // pointer to CStringRep
  54. };
  55.  
  56. Since the object is shared, a reference count field in the class CStringRep is needed to be sure that the CStringRep object is only deleted when there are no more CString objects using it.
  57.  
  58. class CStringRep
  59. {
  60. public:
  61. long Length();
  62. private:
  63. char *fRep;                                // pointer to a string
  64. int fCount;                                // reference count field
  65. };
  66.  
  67. Figure 1-1 on page 5 illustrates the state of two string objects a and b after the assignment b = a. While a and b name separate CString objects, both objects point to the same CStringRep object.
  68. Figure 11 How to handle strings with reference counting
  69. Adding reference-counted pointers
  70. FW_TCountedPtr makes it relatively easy to add reference counting to a design. You can modify the above design to use FW_TCountedPtr very easily, by doing the following two things:
  71. 1) Implement the methods IncrementReferenceCount and DecrementReferenceCount in the class CStringRep. This is the interface FW_TCountedPtr uses to adjust the reference count inside the representation object.
  72. 2) Use the template class FW_TCountedPtr<CStringRep> in place of the class CString. This might be done using a typedef:
  73. typedef CString FW_TCountedPtr<CStringRep>;
  74. Objects of FW_TCountedPtr<T> behave very much like pointers to T.
  75. In general, if you want to add reference counting to your own data structures, you will need to design a representation class CYourClassRep and then instantiate FW_TCountedPtr<CYour–ClassRep> for your class. Whenever a reference-counted pointer class is used, there must be a corresponding representation class. This representation class is generally an implementation detail. FW_TCountedPtr makes no effort to hide these implementation details.
  76. Idioms for using reference-counted pointers
  77. It is much more convenient to type and read the name CString than it is to type and read the name FW_TCountedPtr<CString–Rep>. For these reasons, it is generally preferable to encapsulate the reference-counted pointer within another class. You can subclass FW_TCountedPtr, but that is generally not good C++ style. Instead, create a new class that contains a FW_TCountedPtr<T> field. For example, you can modify CString as follows:
  78.  
  79. class CString
  80. {
  81. public:
  82. long Length() {fRep->Length();}
  83. private:
  84. FW_TCountedPtr<CStringRep> fRep;
  85. };
  86.  
  87. With this idiom, you need only look at the CString class, which explicitly reimplements all the functions of CStringRep with inline functions.
  88. Dereferencing
  89. Overloading the dereferencing operator->() is primarily useful for creating smart pointers, that is, objects that act like pointers, and in addition, perform some action whenever another object is accessed through them. The difference between a smart pointer and an ordinary pointer is that a smart pointer is used on an object of a class and is not a pointer to an object. For example, if X is a class with an operator->() method, and Y() is a method of some other class, then
  90. X xobj;
  91. xobj->Y();
  92. is evaluated as
  93. (xobj.operator->())->Y();
  94. This means that operator->() must return an object of a class. This class must contain a definition for operator->(). The operator->() is then called again for the new object and this process is repeated recursively until the result is a pointer to a class object containing the Y() method.
  95. FW_TCountedPtr<T> implements operator->(), but a client of FW_TCountedPtr<T> must look at the interface of T to know what fields are available (and accessible). For example, you must look at the interface of CStringRep (below) to know that the public method, Length(), is accessible to FW_TCounted–Ptr<CStringRep>.
  96.  
  97. class CStringRep
  98. {
  99. public:
  100. long Length();
  101. private:
  102. char *fRep;                                // pointer to a string
  103. int fCount;                                // reference count field
  104. };
  105.  
  106. FW_TCountedPtr subclasses
  107. There are no subclasses of this class.
  108. Related classes
  109. OPF uses reference counting in the Files, Graphics, and Resources components.
  110. Subclassing FW_TCountedPtr
  111. You might subclass FW_TCountedPtr<CYourClassRep> and name the resulting class CYourClass. This would allow you to add extra constructors and provide a more convenient class name. However, you should be sure to read the section “Idioms for using reference-counted pointers” on page 6, since it is generally preferable to not subclass this class.
  112. FW_TCountedPtr Methods
  113.  
  114. FW_TCountedPtr();
  115.  
  116. Default constructor. Creates a NULL pointer (a pointer whose value is 0). Such an instance does not point to any representation object.
  117.  
  118. FW_TCountedPtr(tRepresentation* rep);
  119.  
  120. Creates a new reference-counted pointer that points to the representation object passed in as a parameter, and increments the reference count by one.
  121.  
  122. FW_TCountedPtr(const FW_TCountedPtr<tRepresentation>& other);
  123.  
  124. Copy constructor. Creates a new reference-counted pointer that points to the same representation object as the other reference-counted pointer points to, and increments the reference count by one.
  125.  
  126. ~FW_TCountedPtr();
  127.  
  128. Destroys the reference-counted pointer. Decrements the reference count in the representation object and deletes the representation object if the reference count is zero.
  129.  
  130. int operator!=(const FW_TCountedPtr<tRepresentation>& other) const;
  131.  
  132. Returns TRUE if the reference-counted pointer points to a different representation object and FALSE if it does not. 
  133.  
  134. tRepresentation& operator*() const;
  135.  
  136. Provides access to the representation object. This operator should be used only if operator->() is not sufficient.
  137.  
  138. tRepresentation* operator->() const;
  139.  
  140. Provides access to fields of the representation object. For more information on smart pointers, see “Dereferencing” on page 6.
  141.  
  142.  
  143. FW_TCountedPtr<tRepresentation>& operator=(const FW_TCountedPtr<tRepresentation>& other);
  144.  
  145. Assignment operator. Point this reference-counted pointer to the same representation object as the other reference-counted pointer points to, and increment the reference count by one.
  146.  
  147. FW_TCountedPtr<tRepresentation>& operator=(tRepresentation* rep);
  148.  
  149. Assignment operator. Point this reference-counted pointer to the representation object passed in as a parameter, and increment the reference count by one.
  150.  
  151. int operator==(const FW_TCountedPtr<tRepresentation>& other) const;
  152.  
  153. Returns TRUE if the reference-counted pointer points to the same representation object and FALSE if it does not.
  154.  
  155. operator const void*() const;
  156.  
  157. Use to test if the reference-counted pointer is a NULL pointer.
  158. ¶dˇ ˇˇˇˇd
  159. d
  160. 4¥læ
  161. ,Times
  162. .˝`(ªèOPF Reference Manual)v1
  163. ˇˇˇˇˇˇˇˇt¥¯Δ
  164. Ω
  165. ΔΩ¯¥Ω
  166. p¥¯Δ
  167. Ω
  168. ΔΩ¯¥Ω
  169.  ΩlΩÔ
  170. $¿Ä°dONLNd{xüÎ(ñx    Utilities∂İdONLNd
  171. ü@√Ï(∫@    Component¿°dONLNdˇˇ+ö$1
  172. °dONLNd·2(· Introduction, Palatino
  173. °dONLNd"·$Ù*The ª¿°dONLNd&Ù$K)Utilities component°dONLNd9L$¸)X, is a collection of miscellaneous utilities °dONLNde$·0Á(-·:which don’t logically belong in the other OPF components. °dONLNdü0·<ï* ,Currently, there is only one utility in the Q`°dONLNdÀ0ñ<Ì)µUtilities component•†°dONLNdfi0Ì<)W: the °dONLNd‰<·HS(E·reference counting utility.
  174. °dONLNdS·b£*Utilities Component Overview
  175. °dONLNdg·sÙ*The ª¿°dONLNd!gÙsK)Utilities component°dONLNd4gLs)X+ contains 1 class and 11 methods. You will °dONLNd_s·‘(|·8likely need to know about, and use, the majority of the †°dONLNdós’˙)Ù
  176. Utilities °dONLNd°·ã(à·    component` °dONLNd™ã>)2     methods.
  177. °dONLNd¥ñ·¢(ü·    Directory,
  178. Courier
  179. .°dONLNdæ§·∞*FWFoundU
  180. .°dONLNd«ª·«
  181. *Heritage
  182. .°dONLNd–÷ÿ5*FW_TCountedPtr.°dONLNdˇˇ)\.°dONLNdˇˇ) .°dONLNdˇˇ)
  183. .°dONLNdˇˇ) .°dONLNdˇˇ)
  184. .°dONLNdˇˇ) .°dONLNdˇˇ)
  185. .°dONLNdˇˇ) .°dONLNdˇˇ)
  186. .°dONLNdˇˇ) .°dONLNdˇˇ)
  187. .°dONLNdˇˇ) .°dONLNdˇˇ)
  188. .°dONLNdˇˇ) .°dONLNdˇˇ)
  189. .°dONLNdˇˇ) .°dONLNdflÃÿ
  190. )
  191. 3
  192. °dONLNd···ÌD(Í·Utilities component!@°dONLNdÙ·EÌi)d classes
  193. °dONLNd˝Ô·˚b(¯·There is only one class in the ÷°dONLNdÔb˚π)ÅUtilities component*@°dONLNd/Ô∫˚ø)X, .°dONLNd1˚·5(·FW_TCountedPtr°dONLNd?˚5Õ)T$, which is at the root level of the °dONLNdc˚Õ¯)ò
  194. Utilities .°dONLNdm·(·    component` °dONLNdv)2.
  195. °dONLNdx·*D('·Utilities component!@°dONLNdãE*s)d     concepts
  196. °dONLNdï,·8Ù(5·The ª¿°dONLNdô,Ù8K)Utilities component°dONLNd¨,L8˝)X( provides the reference-counted pointer ˇ˛Êf.°dONLNd‘8·D%(A·template class, ˇ¸≥2LðdONLNd‰8&Dz)EFW_TCountedPtrˇ˛ÊfLðdONLNdÚ8zD‡)T, to make it easier to use ôñ°dONLNd
  197. 8‡D    )f
  198. reference .°dONLNdD·P(M·counting †°dONLNdDP˘)$9. The goal of reference counting is to keep track of how ˇˇª'°dONLNdXP·\    (Y·Dmany times an object is referenced so an unreferenced object can be ˇˇô°dONLNdú\·h    * Cautomatically deleted. For more information on reference counting, °dONLNdflh·tÒ* see –@°dONLNd„hÒtì) “Using FW_TCountedPtr” on page 3:`°dONLNdhîtñ)£.
  199. °dONLNd·ã(à· Additional +¿°dONLNdã~):Utilities componentÕ°dONLNd#~ã≤)c  interfaces
  200. °dONLNd/ç·ôw(ñ·#There are no additional interfaces.ˇJdˇ ˇˇˇˇd
  201. d
  202. 4oly¯,Times
  203. .+lx1)Utilities Component ~l~¯4≥ZΩ¯
  204. (πZ2)OPF Reference Manual
  205. ˇˇˇˇˇˇˇˇtzZÉc~cÉ^~Zz^~cpzZÉc~cÉ^~Zz^~c
  206. 4êœö¯
  207. °dONLNdèœõQ(òœComponent dependencies, Palatino
  208. °dONLNdúœ®€*
  209. <Reference-counted pointers are particularly useful when the ˇˇ˛J°dONLNdS®œ¥˜* Epointers are value-based, automatic (stack-based) variables. This is °dONLNdò¥œ¿Ù* Atrue because OPF takes advantage of C++ exception handling. If a °dONLNdŸ¿œÃfl* ?reference-counted pointer is a stack-based variable in a given °dONLNdÜÿ⁄* ?scope, and an exception is thrown out of the scope, then it is °dONLNdWÿœ‰Ï* Bimportant that the destructor of the reference-counted pointer is ˇˇ§œ°dONLNdô‰œ˜* Cexecuted. When OPF is built with compilers that do not yet provide °dONLNd‹œ¸ÿ* :exception handling, OPF uses the OPF Exception Library to .°dONLNd¸œÅ* &provide exception handling emulation. ,
  210. Courier°dONLNd<¸Å’)≤FW_TCountedPtr°dONLNdJ¸’◊)T .°dONLNdKœ‚(œ=depends upon exception handling, so if the compiler does not .°dONLNdàœ O* support exception handling, °dONLNd§O £)ÄFW_TCountedPtr°dONLNd≤£ ı)T depends upon the ˇˇò°dONLNdƒ œ,()œBEL component, ˇ˝L»≥0°dONLNd” ,F)GFWExcLibˇˇò≥0°dONLNd€ F,˜)0(. When OPF is built with compilers that °dONLNd,œ8O(5œsupport exception handling, °dONLNd,O8£)ÄFW_TCountedPtr°dONLNd-,£8Î)T is entirely self-.°dONLNd?8œDÊ(Aœ;contained and is not dependent on any other OPF components.
  211. °dONLNd{Pœ_è*Using the Utilities Component
  212. °dONLNdôcœoÚ*Use the +@°dONLNd°cÛoJ)$Utilities componentİdONLNd¥cJoÌ)W$ to keep track of how many times an °dONLNdÿoœ{ˆ(xœDobject is referenced so an unreferenced object can be automatically °dONLNd{œáÚ* deleted.
  213. °dONLNd%ìœüD*Subclassing within the +°dONLNd<ìEü®)vUtilities component
  214. ˇˇ8‚.°dONLNdP†œ¨C(©œAlthough you can subclass ˇ˝™¶cà°dONLNdj†D¨ò)uFW_TCountedPtrˇˇ8‚cà°dONLNdx†ò¨¯)T, that is generally not .°dONLNdꨜ∏‘(µœ=good C++ style. Instead, you will typically be instantiating .°dONLNdÕ∏œƒ#* FW_TCountedPtr°dONLNd€∏#ƒ&)T.
  215. .°dONLNd›–œ‹J(ŸœInstantiating within the &İdONLNdˆ–K‹Æ)|Utilities component
  216. .°dONLNd
  217. ›œÈA(ÊœYou instantiate the class °dONLNd$›AÈï)rFW_TCountedPtr°dONLNd2›ïÈò)T.
  218. .°dONLNd4ıœ(˛œExtending the )°dONLNdBı})KUtilities component
  219. °dONLNdVœá( œ,It is generally not necessary to extend the g°dONLNdÇàfl)πUtilities componentª@°dONLNdïfl·)W.
  220. °dONLNdóœ&(#œ    Catching (İdONLNd†&d)2Utilities component…¿°dONLNd≥d&ú)c  exceptions
  221. °dONLNdø'œ3(0œMethods in the ∏°dONLNdŒ'3k)EUtilities component @°dONLNd·'l3‹)X do not throw exceptions.
  222. °dONLNd˚?œKf(HœPlatform dependencies in the sİdONLNd?gK )òUtilities component
  223. °dONLNd,LœX‡(Uœ:There are no platform-dependent methods in this component.ˇ bdˇ ˇˇˇˇd
  224. d
  225. 4¥læ
  226. ,Times
  227. .˝`(ªèOPF Reference Manual)v34ë·õ
  228. 
  229. ¸@°dONLNdèW¢›(ùWFW_TCountedPtr˛°dONLNd蛢    )Ü Class
  230. °dONLNd∫·…2(≈· Introduction,
  231. Courier
  232. .°dONLNd"Œ·⁄5*FW_TCountedPtr, Palatino°dONLNd0Œ5⁄˛)T, provides a mechanism for reference-counted .°dONLNd\⁄·ÊÔ(„·?pointers. A reference-counted pointer points to an object of a .°dONLNdõÊ·Ú!* specific type (°dONLNd™Ê!Ú{)@tRepresentation°dONLNdπÊ{Ú)Z ) that must contain an internal .°dONLNdŸÚ·˛'(˚·reference count..°dONLNdÍ·Ù*Use °dONLNdÓÙH)FW_TCountedPtr°dONLNd¸H¯)T* to adjust the reference count inside the .°dONLNd&· Â(·;representation object. When a reference-counted pointer is:°dONLNdb*Û6˘+•ˇˇöLÕ°dONLNdd*˛6¯) <copied, the reference count in the representation object is LÕ°dONLNd†6˛B7* incremented.°dONLNd≠LÛX˘(UÛ•LÕ°dONLNdØL˛Xı) :deleted, the reference count in the representation object LÕ°dONLNdÈX˛dC* is decremented.ˇˇÒ√°dONLNd˘n·z    (w·DDisposing of a single reference-counted pointer does not delete the °dONLNd=z·Ü* Hrepresentation object, if it is still being accessed by other reference-°dONLNdÖÜ·íÔ* =counted pointers. When the reference count goes to zero, the °dONLNd¬í·ûl* !representation object is deleted.
  233. °dONLNd‰©·µ* Header file
  234. .°dONLNd∑·√*
  235. FWCouPtr.h
  236. .°dONLNd˚Œ·⁄
  237. *Heritage
  238. .°dONLNdfl·ÎC*FW_TCountedPtr
  239. .°dONLNdÙ·    *Using Ó°dONLNdÙ    ~)(FW_TCountedPtr
  240. ˇˇé8.°dONLNd(·Û(·Use ˇ˛™®8°dONLNd,ÙH)FW_TCountedPtrˇˇé88°dONLNd:H
  241. )T. for classes whose instances are often copied .°dONLNdh· Ó(·=through assignment or parameter passing, particularly if the °dONLNd• ·,Î* >objects are so large or complex that copying is expensive. In °dONLNd„,·8˘* ?addition, use reference-counted pointers when multiple logical °dONLNd"8·D¯* Bcopies of an object might exist, though the data itself cannot be °dONLNddD·P* copied.°dONLNdlZ·f* Overview of Î@°dONLNdxZff)6reference counting°dONLNdãd·pˆ(m·;Suppose you are developing a part where you will have many °dONLNdΔp·|ı* Astring objects which might contain a small set of string values. .°dONLNd|·àñ* )Assume you want to create a string class,°dONLNd0|ñàΔ)µ CString°dONLNd8|ΔàÛ)0 , that can .°dONLNdCà·î(ë·@minimize storage requirements by sharing the representation for ˇ
  242. ídˇ ˇˇˇˇd
  243. d
  244. 4oly¯,Times
  245. .+lx1)Utilities Component ~l~¯4≥ZΩ¯
  246. (πZ4)OPF Reference Manual
  247. ˇˇˇˇˇˇˇˇtzZÉc~cÉ^~Zz^~cpzZÉc~cÉ^~Zz^~c
  248. 4êœö¯, Palatino.°dONLNdçœôC(ñœthe string data when two ,
  249. Courier°dONLNdçCôm)tCString°dONLNd çmô¯)*! objects contain the same string .°dONLNdAôœ•Í(¢œBdata. The representation is itself an object, managing the shared ˇˇàì°dONLNdÉ•œ±˜* Ddata and an associated reference count. You will need to design two .°dONLNd«±œΩÛ*     classes: °dONLNd–±ÛΩ)$CString°dONLNd◊±Ω2)* and °dONLNd‹±2Ωn)
  250. CStringRep°dONLNdʱnΩq)<.°dONLNdË«œ”(–œ
  251. In the class °dONLNdı«”.)5CString°dONLNd¸«.”¯)*+, implement the assignment operator (among .°dONLNd'”œfl·(‹œ@others) such that assigning one string to another string causes °dONLNdgflœÎP* sharing of the representation.
  252. ˜œ˛¯4¯œ˛¯ ˚œ˚¯
  253. d.°dONLNdá˚œ*
  254. class CString°dONLNd*
  255. {°dONLNdóœ˘*
  256. public:°dONLNdü·%°+
  257.  operator=(const CString& other);°dONLNd¿#·/Á*
  258. …°dONLNd¬7œCˇ(@œprivate:°dONLNdÀA·MG+
  259. CStringRep *fRep;°dONLNd‰A_MÔ)~// pointer to CStringRep
  260. Wœ^¯4Xœ^¯ [œ[¯
  261. d°dONLNd˝KœW€(Tœ};.°dONLNdgœsŸ*ASince the object is shared, a reference count field in the class .°dONLNdBsœ *
  262. CStringRep°dONLNdLs ç)< is needed to be sure that the °dONLNdksç…)Ç
  263. CStringRep°dONLNdus…)<  object is °dONLNdÄœãu(àœ$only deleted when there are no more °dONLNd§uãü)¶CString°dONLNd´üã‰)* objects using it.
  264. óœû¯4òœû¯ õœõ¯
  265. d°dONLNdøõœß/(§œclass CStringRep°dONLNd–•œ±’*
  266. {°dONLNd“Øœª˘*
  267. public:°dONLNd⁄π·≈5+
  268. long Length();°dONLNdÈ√·œÁ*
  269. …°dONLNdÎ◊œ„ˇ(‡œprivate:°dONLNdÙ··Ì#+
  270. char *fRep;°dONLNd·_Ì„)~// pointer to a string°dONLNdη˜#(Ù· int fCount;°dONLNd1Î_˜Ô)~// reference count field
  271. œ¯4œ¯ œ¯
  272. d°dONLNdJıœ€(˛œ};ˇˇ€l°dONLNdNœˆ*    Figure 1-[l°dONLNdW˜¸)(1[l°dONLNdX¸    ) on D°dONLNd\
  273. &)page 5Ì∞°dONLNdb&‹)- illustrates the state of two string objects ˇˇíD…°dONLNd蛄)∑aˇˇ€l…°dONLNdꄘ) and °dONLNdïœ)’(&œb°dONLNdñ’)6) after the assignment °dONLNd¨6)T)ab = a°dONLNd±T)z). While °dONLNdπz)Ä)&a°dONLNd∫Ä)ï) and °dONLNdøï)õ)b°dONLNd¿õ)·) name separate °dONLNdœ)œ5˘(2œCString°dONLNd÷)˘5£)*) objects, both objects point to the same °dONLNdˇ)£5fl)™
  274. CStringRep°dONLNd    )fl5·)< .°dONLNd
  275. 5œAÎ(>œobject.ˇ‚dˇ ˇˇˇˇd
  276. d
  277. 4rl|¯,Times
  278. .ÿ¿(zÇUsing FW_TCountedPtr4¥læ
  279. ˝`(ªèOPF Reference Manual)v5
  280. ˇˇˇˇˇˇˇˇtzÉ
  281. ~
  282. É~z~
  283. pzÉ
  284. ~
  285. É~z~
  286.  ~l~¯
  287. 4ë·õ
  288. , Palatino°dONLNdˇˇ(k·    Figure 1-‡°dONLNdˇˇ)(1 ù‡°dONLNdˇˇ)-How to handle strings with reference counting
  289. °dONLNdˇˇ(g 1
  290. °dONLNdv·Çu(·!Adding reference-counted pointers,
  291. Courier.°dONLNd"Ä·å5*
  292. FW_TCountedPtr°dONLNd0Ä5åÛ)T+ makes it relatively easy to add reference .°dONLNd[å·òÛ(ï·=counting to a design. You can modify the above design to use ˇˇ†.°dONLNdòò·§5* FW_TCountedPtrˇˇ‡°dONLNd¶ò5§
  293. )T0 very easily, by doing the following two things:°dONLNd◊Æ·∫Z(∑·1) Implement the methods °dONLNdÆZ∫‰)yIncrementReferenceCount°dONLNdƉ∫˘)ä and °dONLNd ∫·Δk(√·DecrementReferenceCount°dONLNd#∫kΔ¢)ä in the class °dONLNd1∫¢Δfi)7
  294. CStringRep°dONLNd;∫fiΔ)<
  295. . This is °dONLNdEΔ·“(œ·the interface °dONLNdSΔ“r)=FW_TCountedPtr°dONLNdaΔr“)T$ uses to adjust the reference count .°dONLNdÖ“·fim(€·!inside the representation object..°dONLNdßË·ÙS*2) Use the template class°dONLNd¿ËSÙY)r °dONLNd¡ËYÙ≠)FW_TCountedPtr°dONLNdœË≠Ù˚)T
  296. <CStringRep> °dONLNd‹Ë˚Ù)Nin °dONLNdflÙ·1(˝·place of the class °dONLNdÚÙ1[)PCString°dONLNd˘Ù[)*%. This might be done using a typedef:°dONLNd
  297. ÛS(Ûtypedef CString °dONLNd/
  298. Sß)`FW_TCountedPtr°dONLNd=
  299. ßı)T
  300. <CStringRep>;ˇˇïT°dONLNdK·* ('·
  301. Objects ofˇ˛ø¸T°dONLNdU *)+ ’P°dONLNdV*d)FW_TCountedPtr’P°dONLNddd*z)T<T> ˇˇïTïL°dONLNdh{*    )behave very much like pointers °dONLNdá*·6Ï(3·to °dONLNdä*Ï6Ú) T°dONLNdã*Ú6ı).ˇˇ˚>.°dONLNdç@·L    (I·CIn general, if you want to add reference counting to your own data °dONLNd–L·XÉ* &structures, you will need to design a kİdONLNdˆLÑXΩ)£representation/°dONLNdLæX◊): class .°dONLNd X·d/(a·
  302. CYourClassRep°dONLNdX/dé)N and then instantiate°dONLNd-Xédî)_ 
  303. l·s
  304. 4l·r
  305.  o·o
  306. 
  307. d
  308.     .°dONLNdˇˇ(xÛ1. °dONLNdˇˇ)        Figure 1-+†°dONLNdˇˇ)$1´†°dONLNdˇˇ) was adapted from çİdONLNdˇˇ)M Advanced C++ programming styles ‹(°dONLNdˇˇ(ɸ
  309. and idiomsõ»°dONLNdˇˇ)(+, by James O. Coplien (AT&T Bell Telephone 
  310. ë·ò
  311. 4ë·ó
  312.  î·î
  313. 
  314. d‹(°dONLNdˇˇ(é¸Laboratories, Inc., 1992)
  315. ól^
  316. TÆs‹ÈX
  317. ɰdONLNdˇˇ(ËèCString object¿?°dONLNdˇˇ(…}CStringRep *fRep;f°dONLNdˇˇ(•¨a—ñ°dONLNdˇˇ( ´bP’¯í ˜¯˜í"≥“$TsBÈXɰdONLNdˇˇ(NèCString object¿?°dONLNdˇˇ(.}CStringRep *fRep;"“$«Ñ°dONLNdˇˇ()CStringRep object"€qˇ:0ÿ≠˜´b°dONLNdˇˇ(ε“Hello World!”Ä#°dONLNdˇˇ(Ó char *fRep;Ä#°dONLNdˇˇ* int fCount;
  318. ˇˇˇˇˇˇˇˇtŸı„ˇŸ˘„ˇ›ı€˜Ÿ˘"¬fit ÙˇÙ ˇ˘ˆÙ",fiËtÊüÏ´ÊüÈ´ÏüÈüÊü"È~!Ä3°dONLNdˇˇ(y2’ä°dONLNdˇˇ+
  319. @CString a = “Hello World!”;’ä°dONLNdˇˇ* CString b = a;ˇ»dˇ ˇˇˇˇd
  320. d
  321. 4oly¯,Times
  322. .+lx1)Utilities Component ~l~¯4≥ZΩ¯
  323. (πZ6)OPF Reference Manual
  324. ˇˇˇˇˇˇˇˇtzZÉc~cÉ^~Zz^~cpzZÉc~cÉ^~Zz^~c
  325. 4êœö¯,
  326. Courierˇ˛∂ÿ.°dONLNdçœô#(ñœFW_TCountedPtr°dONLNdç#ôá)T<CYour–ClassRep> , PalatinoˇˇíH6ÿ°dONLNdçàô¯)efor your class. Whenever .°dONLNd8ôœ•ü(¢œ1a reference-counted pointer class is used, there F@°dONLNdiô†•¥)—must‘ °dONLNdmô¥• ) be a °dONLNds•œ±Á(ÆœAcorresponding representation class. This representation class is .°dONLNd¥±œΩw* $generally an implementation detail. °dONLNdÿ±wΩÀ)®FW_TCountedPtr°dONLNdʱÀΩ¯)T
  327.  makes no .°dONLNdΩœ…ç(Δœ,effort to hide these implementation details.°dONLNd”œflä*+Idioms for using reference-counted pointers.°dONLNdI›œÈø*
  328. 5It is much more convenient to type and read the name °dONLNd~›øÈÈ)CString°dONLNdÖ›ÈÈÎ)* °dONLNdÜÈœıq(Úœ$than it is to type and read the name°dONLNd™Èqıw)¢ °dONLNd´ıœ(˛œ FW_TCounted°dONLNd∂ıq)BPtr<CString–Rep>°dONLNdΔıq‹)`. For these reasons, it is .°dONLNd·œ
  329. Ò(
  330. œBgenerally preferable to encapsulate the reference-counted pointer ˇˇé8.°dONLNd#
  331. œy* 'within another class. You can subclass ˇ˛™®’P°dONLNdJ
  332. yÕ)™FW_TCountedPtrˇˇé8’P°dONLNdX
  333. Õ˜)T , but that .°dONLNdcœ%Ë("œBis generally not good C++ style. Instead, create a new class that .°dONLNd•%œ1˛* contains a °dONLNd∞%˛1R)/FW_TCountedPtr°dONLNdæ%R1j)T<T> °dONLNd¬%j1Ê)field. For example, you can °dONLNdfi1œ=Ú(:œmodify °dONLNdÂ1Ú=)#CString°dONLNdÏ1=O)*  as follows:
  334. IœP¯4JœP¯ MœM¯
  335. d°dONLNd˙MœY(Vœ
  336. class CString°dONLNdWœc’*
  337. {°dONLNd
  338. aœm˘*
  339. public:°dONLNdk·wõ+
  340. long Length() {fRep->Length();}°dONLNd2uœÅ’(~œ…°dONLNd4œãˇ*
  341. private:°dONLNd=â·ï5+
  342. FW_TCountedPtr°dONLNdKâ5ï°)T<CStringRep> fRep;
  343. üœ¶¯4†œ¶¯ £œ£¯
  344. d°dONLNd^ìœü€(úœ};ˇˇ’T°dONLNdbØœªë*+With this idiom, you need only look at the ˇˇ¸ˇÙ°dONLNdçØëªª)¬CStringˇˇ’TˇÙ°dONLNdîØªª˜)* class, which °dONLNd¢ªœ«ñ(ƒœ-explicitly reimplements all the functions of °dONLNdœªñ«“)«
  345. CStringRep°dONLNdŸª“«Ì)< with .°dONLNdfl«œ”(–œinline functions.°dONLNdÒ›œÈ *
  346. Dereferencing.°dONLNdˇÁœÛZ*
  347. Overloading the dereferencing°dONLNdÁZÛÆ)ã operator->() °dONLNd*ÁÆÛË)T
  348. is primarily .°dONLNd7Ûœˇ(¸œuseful for creatingD‡°dONLNdJÛ ˇ")Q ƒ‡°dONLNdKÛ"ˇ\)smart pointers\‡°dONLNdYÛ]ˇÿ);!, that is, objects that act like °dONLNdzˇœ Ú(œ@pointers, and in addition, perform some action whenever another °dONLNd∫ œÏ* @object is accessed through them. The difference between a smart °dONLNd˙œ#* Cpointer and an ordinary pointer is that a smart pointer is used on ˇˇññ.°dONLNd=#œ/€* an ñ°dONLNd@#‹/ı)
  349. objectñ°dONLNdF#ı/S) of a class and is not a ÀF°dONLNd_#S/t)^pointerÀF°dONLNdf#t/)! to an object. For example, if ˇ˛√¬È`°dONLNdÖ#/ˆ)|XˇˇññÈ`°dONLNdÜ#ˆ/˜) ˇˇ’T°dONLNdá/œ;(8œis a class with anˇˇ¸’P°dONLNdô/;n)M operator->() ˇˇ’T’H°dONLNdß/o;©)S method, and ˇˇ¸°dONLNd≥/™;¡);Y() ˇˇ’TˇÏ°dONLNd∑/¡;˜) is a method .°dONLNd√;œG;(Dœof some other class, then.°dONLNd›Q·] +X xobj;°dONLNdÂ[·g*
  350.  
  351. xobj->Y();.°dONLNdoœ{(xœis evaluated as.°dONLNdÖ·ëw+(xobj.operator->())->Y();ˇHdˇ ˇˇˇˇd
  352. d
  353. 4rl|¯,Times
  354. .ÿ¿(zÇUsing FW_TCountedPtr4¥læ
  355. ˝`(ªèOPF Reference Manual)v7
  356. ˇˇˇˇˇˇˇˇtzÉ
  357. ~
  358. É~z~
  359. pzÉ
  360. ~
  361. É~z~
  362.  ~l~¯
  363. 4ë·õ
  364. , Palatino.°dONLNdè·õ+(ò·This means that,
  365. Courier°dONLNdè+õ)J operator->() °dONLNdèõ    )T"must return an object of a class. °dONLNd?õ·ßè(§·(This class must contain a definition for°dONLNdgõèß›)Æ
  366.  operator->()°dONLNdtõ›ßÙ)N. The°dONLNdyõÙß˙) °dONLNdzß·≥/(∞·
  367. operator->() °dONLNdáß/≥)N1is then called again for the new object and this ˇˇœ6.°dONLNd∏≥·ø    (º·Iprocess is repeated recursively until the result is a pointer to a class .°dONLNdø·À?* object containing the °dONLNdø?ÀQ)^Y()°dONLNdøQÀy) method.°dONLNd#’··5(fi·FW_TCountedPtr°dONLNd1’5·M)T<T> °dONLNd5’M·Ç)
  368. implements°dONLNd?’Ç·–)5
  369.  operator->()°dONLNdL’–·    )N, but a client °dONLNd[··ÌÍ(Í·of°dONLNd]·ÍÌ)     °dONLNd^·ÌD)FW_TCountedPtr°dONLNdl·DÌ\)T<T> °dONLNdp·\Ì›)must look at the interface of °dONLNd鷛̄)ÅT°dONLNdè·„Ì
  370. )     to know .°dONLNdòÌ·˘î(ˆ·*what fields are available (and accessible)
  371. ˘†°dONLNdˇˇ(Úî2
  372. ˘†°dONLNd¬Ìò˘+. For example, you must .°dONLNd⁄˘·K(·look at the interface of °dONLNdÛ˘Ká)j
  373. CStringRep°dONLNd˝˘á¸)< (below) to know that the °dONLNd·'(·public method, °dONLNd&'W)FLength()°dONLNd.Wû)0, is accessible to°dONLNd@û§)G °dONLNdA§Ê) FW_TCounted°dONLNdLÊÏ)B–°dONLNdM·;(·Ptr<CStringRep>°dONLNd\;>)Z.
  374. )·0
  375. 4)·/
  376.  ,·,
  377. 
  378. d°dONLNd_-·9A(6·class CStringRep°dONLNdp7·CÁ*
  379. {°dONLNdrA·M *
  380. public:°dONLNdzKÛWG+
  381. long Length();°dONLNdâUÛa˘*
  382. …°dONLNdãi·u(r·private:°dONLNdîsÛ5+
  383. char *fRep;°dONLNdßsqı)~// pointer to a string°dONLNdæ}Ûâ5(ÜÛ int fCount;°dONLNd—}qâ)~// reference count field
  384. ì·ö
  385. 4ì·ô
  386.  ñ·ñ
  387. 
  388. d°dONLNdÍá·ìÌ(ê·};
  389. .°dONLNdÓ§·∞>*FW_TCountedPtrzİdONLNd¸§?∞u)^  subclasses
  390. °dONLNd≤·æÄ(ª·&There are no subclasses of this class.
  391. °dONLNd/…·’-*Related classes
  392. °dONLNd?◊·„*BOPF uses reference counting in the Files, Graphics, and Resources °dONLNdÅ„·Ô* components.
  393. °dONLNdç˙· * Subclassing ɰdONLNdô˙ })?FW_TCountedPtr
  394. .°dONLNd®·6(·You might subclass°dONLNd∫6<)U °dONLNdª<ê)FW_TCountedPtr°dONLNd…ê)T<CYourClassRep> °dONLNdŸ)`and °dONLNd›· O(·name the resulting class °dONLNdˆO ã)n
  395. CYourClass°dONLNdã ˇ)<. This would allow you to .°dONLNd ·,()·Aadd extra constructors and provide a more convenient class name. ˇˇ˙À°dONLNd[,·8π* 0However, you should be sure to read the section ›c°dONLNdã,π8    )ÿ“Idioms for using °dONLNdù8·Dâ(A·%reference-counted pointers” on page 6i‡°dONLNd¬8äDÂ)©, since it is generally °dONLNd⁄D·P}(M·&preferable to not subclass this class.
  396. Ç·â
  397. 4Ç·à
  398.  Ö·Ö
  399. 
  400. ë·ò
  401. 4ë·ó
  402.  î·î
  403. 
  404. d
  405.     .°dONLNdˇˇ+A%2. In general, all public methods of °dONLNdˇˇ)àT°dONLNdˇˇ) are accessible.ˇ‡dˇ ˇˇˇˇd
  406. d
  407. 4oly¯,Times
  408. .+lx1)Utilities Component ~l~¯4≥ZΩ¯
  409. (πZ8)OPF Reference Manual
  410. ˇˇˇˇˇˇˇˇtzZÉc~cÉ^~Zz^~cpzZÉc~cÉ^~Zz^~c
  411. 4êœö¯
  412. °dONLNdèœûD(öœFW_TCountedPtr˛¿°dONLNdèDû)u Methods
  413. §œ´¯4•œ´¯ ®œ®¯
  414. ¥œª¯4µœª¯ ∏œ∏¯
  415. d,
  416. Courier
  417. .°dONLNd®œ¥#(±œFW_TCountedPtr°dONLNd&®#¥5)T();, Palatino.°dONLNd+Ωœ…'(ΔœDefault constructor.◊†°dONLNd?Ω'…‚)X) Creates a NULL pointer (a pointer whose °dONLNdh…œ’Ô(“œCvalue is 0). Such an instance does not point to any representation °dONLNd´’œ·Î* object.
  418. ̜ٯ4Ӝٯ ÒœÒ¯
  419. ˝œ¯4˛œ¯ œ¯
  420. d.°dONLNd¥Òœ˝#*FW_TCountedPtr°dONLNd¬Ò#˝≠)T(tRepresentation* rep);.°dONLNd€œ“(œ;Creates a new reference-counted pointer that points to the °dONLNdœˆ* Crepresentation object passed in as a parameter, and increments the °dONLNdYœ*5* reference count by one.
  421. 6œ=¯47œ=¯ :œ:¯
  422. d.°dONLNdr:œF#*FW_TCountedPtr°dONLNdÄ:#FM)T(const 
  423. PœW¯4QœW¯ TœT¯
  424. d°dONLNdáDœP#(MœFW_TCountedPtr°dONLNdïD#Pø)T<tRepresentation>& other);.°dONLNd±Yœe(bœCopy constructor.Ë¿°dONLNd¬YeÈ)O. Creates a new reference-counted pointer that °dONLNdeœq‚(nœ@points to the same representation object as the other reference-°dONLNd0qœ}Ô* Acounted pointer points to, and increments the reference count by °dONLNdq}œâ·* one.
  425. ïœú¯4ñœú¯ ôœô¯
  426. •œ¨¯4¶œ¨¯ ©œ©¯
  427. d.°dONLNdwôœ•’*~°dONLNdxô’•))FW_TCountedPtr°dONLNdÜô)•;)T();.°dONLNdãÆœ∫Û(∑œADestroys the reference-counted pointer. Decrements the reference °dONLNdÃ∫œΔÏ* Bcount in the representation object and deletes the representation °dONLNdΔœ“j* &object if the reference count is zero.
  428. fiœÂ¯4flœÂ¯ ‚œ‚¯
  429. d.°dONLNd6‚œÓÁ*int °dONLNd:‚ÁÓM)operator!=(const 
  430. ¯œˇ¯4˘œˇ¯ ˚œ˚¯
  431. d°dONLNdKÏœ¯#(ıœFW_TCountedPtr°dONLNdYÏ#¯„)T <tRepresentation>& other) const;ˇˇflS.°dONLNd{œ
  432. ˜(
  433. œDReturns TRUE if the reference-counted pointer points to a different °dONLNdø
  434. œû* 0representation object and FALSE if it does not. 
  435. %œ,¯4&œ+¯ (œ(¯
  436. 5œ<¯45œ;¯ 8œ8¯
  437. d.°dONLNdÒ)œ55*tRepresentation& °dONLNd)55°)foperator*() const;.°dONLNd>œJÚ(GœCProvides access to the representation object. This operator should .°dONLNdYJœV* be used only if°dONLNdhJVc)@ operator->() °dONLNdvJcV´)Tis not sufficient.
  438. bœi¯4bœh¯ eœe¯
  439. rœy¯4rœx¯ uœu¯
  440. d°dONLNdäfœr5(oœtRepresentation* °dONLNdõf5rß)foperator->() const;.°dONLNd∞{œá‰(ÑœAProvides access to fields of the representation object. For more °dONLNdÒáœìi* #information on smart pointers, see İdONLNdájìfl)õ“Dereferencing” on page 6Œ†°dONLNd-áflì·)u.
  441. ©Z¿Δ4©Z¿Δ4´Z√Δ°dONLNdˇˇ(≤ZFW_TCountedPtr
  442. ôZ±Δ4öZ±Δ4úZ¥Δ°dONLNdˇˇ*Ò~≤†°dONLNdˇˇ)FW_TCountedPtr
  443. ‚Z˙Δ4„Z˙Δ4ÂZ˝Δ°dONLNdˇˇ(ÏZ
  444. operator!=
  445. %Z=«4&[=«4([@«UV°dONLNdˇˇ+C    operator*
  446. bZz«4c[z«4e[}«UV°dONLNdˇˇ*<
  447. operator->ˇ    vdˇ ˇˇˇˇd
  448. d
  449. 4rl|¯,Times
  450. .hÄ(zΔ    operator=4¥læ
  451. ˝`(ªèOPF Reference Manual)v9
  452. ˇˇˇˇˇˇˇˇtzÉ
  453. ~
  454. É~z~
  455. pzÉ
  456. ~
  457. É~z~
  458.  ~l~¯
  459. 4ë·õ
  460. 
  461. ë·ò
  462. 4ë·ó
  463.  î·î
  464. 
  465. d,
  466. Courier.°dONLNdï·°5(û·FW_TCountedPtr°dONLNdï5°ß)T<tRepresentation>& °dONLNd!ïß°)roperator=(const 
  467. ´·≤
  468. 4´·±
  469.  Æ·Æ
  470. 
  471. d°dONLNd1ü·´5(®·FW_TCountedPtr°dONLNd?ü5´—)T<tRepresentation>& other);, Palatino.°dONLNd[¥·¿A(Ω·Assignment operator.ô‡°dONLNdo¥A¿)`- Point this reference-counted pointer to the °dONLNdú¿·Ã(…·Bsame representation object as the other reference-counted pointer °dONLNdfi÷ÿΔ* 4points to, and increment the reference count by one.
  472. ‰·Î
  473. 4‰·Í
  474.  Á·Á
  475. 
  476. d.°dONLNdË·Ù5*FW_TCountedPtr°dONLNd"Ë5Ùß)T<tRepresentation>& 
  477. ˛·
  478. 4˛·
  479.  ·
  480. 
  481. d°dONLNd5Ú·˛°(˚· operator=(tRepresentation* rep);.°dONLNdW·A*Assignment operator.ô‡°dONLNdkA)`- Point this reference-counted pointer to the °dONLNdò·(·Brepresentation object passed in as a parameter, and increment the °dONLNd⁄·+G* reference count by one.
  482. 7·>
  483. 47·=
  484.  :·:
  485. 
  486. d.°dONLNdÛ;·G˘*int °dONLNd˜;˘G_)operator==(const 
  487. Q·X
  488. 4Q·W
  489.  T·T
  490. 
  491. d°dONLNdE·Q5(N·FW_TCountedPtr°dONLNdE5Qı)T <tRepresentation>& other) const;.°dONLNd8Z·f(c·AReturns TRUE if the reference-counted pointer points to the same °dONLNdyf·rÆ* /representation object and FALSE if it does not.
  492. ~·Ñ
  493. 4~·Ñ
  494.  Å·Å
  495. 
  496. ç·î
  497. 4é·î
  498.  ë·ë
  499. 
  500. d.°dONLNd™Ç·éè*operator const void*() const;.°dONLNd…ó·£Ú*?Use to test if the reference-counted pointer is a NULL pointer.
  501. ël©Ÿ4ëm®Ÿ4îm¨ŸUV°dONLNdˇˇ(öm    operator=
  502. 7lOŸ47mNŸ49mQŸUV°dONLNdˇˇ*¶
  503. operator==
  504. ~lñŸ4~mïŸ4ÄmòŸUV°dONLNdˇˇ*Goperator const void*ˇ$dˇ ˇˇˇˇd
  505. d
  506. 4oly¯,Times
  507. .+lx1)Utilities Component ~l~¯4≥ZΩ¯
  508. (πZ10)OPF Reference Manual
  509. ˇˇˇˇˇˇˇˇtzZÉc~cÉ^~Zz^~cpzZÉc~cÉ^~Zz^~c
  510. 4êœö¯ˇ